package org.gwt.grin.rebind;

import java.util.Formatter;

import org.gwt.grin.client.util.BgImage;
import org.gwt.grin.client.util.Color;
import org.gwt.grin.client.util.FontSpec;
import org.gwt.grin.client.util.Rectangle;
import org.gwt.grin.rebind.input.SERCHandler;

import com.google.gwt.dom.client.Style.FontStyle;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.uibinder.rebind.IndentedWriter;

public abstract class AbstractSENode implements SENode {

	protected final String name;

	private String vn;
	
	protected AbstractSENode(String name) {
		this.name = name;
	}

	@Override
	public String write(ShowBuilder builder) {
		String cn = getClassName();
		Formatter formatter = new Formatter();
		formatter.format("new %s(\"%s\")", cn, name);
		return formatter.toString();
	}
	
	public String write(IndentedWriter w, ShowBuilder builder, int index) {
		String cn = getClassName();
		String vn = getVN(builder);
		w.write("%s %s = %s;", cn, vn, write(builder));
		return vn;
	}

	protected abstract String getClassName();

	public String getVN(ShowBuilder builder) {
		if (vn == null) {
			vn = builder.buildUniqueName(this.getClass());
		}
		return vn;
	}

	protected String makeRCHandlersArray(ShowBuilder builder,
			SERCHandler[] rcHandlers) {
		StringBuilder sb = new StringBuilder();
		sb.append("new RCHandler[] {");
		boolean first = true;
		for (SERCHandler h : rcHandlers) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(h.getVN(builder));
		}
		sb.append("}");
		return sb.toString();
	}

	protected String makeFeaturesArray(ShowBuilder builder, SEFeature[] features) {
		if(features == null) {
			return "null";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("new Feature[] {");
		boolean first = true;
		for (SEFeature f : features) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(f.getVN(builder));
		}
		sb.append("}");
		return sb.toString();
	}
	
	protected String makeCommandsArray(ShowBuilder builder, SECommand[][] cmds) {
		if (cmds == null) {
			return "null";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("new Command[][] {");
		boolean first = true;
		for (SECommand[] v : cmds) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(makeCommandsArray(builder, v));
		}
		sb.append("}");
		return sb.toString();
	}

	protected String makeCommandsArray(ShowBuilder builder, SECommand[] cmds) {
		if (cmds == null) {
			return "null";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("new Command[] {");
		boolean first = true;
		for (SECommand c : cmds) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(c.getVN(builder));
		}
		sb.append("}");
		return sb.toString();
	}

	protected String makeColor(Color color) {
		if (color == null) {
			return "null";
		}
		int r = color.getRed();
		int g = color.getGreen();
		int b = color.getBlue();
		int a = color.getAlpha();
		return "new Color(" + r + ", " + g + ", " + b + ", " + a + ")";
	}

	protected String makeFontSpec(FontSpec fontSpec) {
		if (fontSpec == null) {
			return "null";
		}
		String name = fontSpec.getName();
		FontStyle style = fontSpec.getStyle();
		FontWeight weight = fontSpec.getWeight();
		int size = fontSpec.getSize();
		return "new FontSpec(\"" + name + "\", Style.FontStyle." + style
				+ ", Style.FontWeight." + weight + ", " + size + ")";
	}

	protected String makeBgImage(BgImage bgImage) {
		if (bgImage == null) {
			return "null";
		}
		String url = bgImage.getUrl();
		String repeat = bgImage.getRepeat();
		String position = bgImage.getRepeat();
		return "new BgImage(\"" + url + "\", \"" + repeat + ",\"" + position
				+ "\")";
	}

	protected String makeRectangleArray(Rectangle[] rectangles) {
		if (rectangles == null) {
			return "null";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("new Rectangle[] {");
		boolean first = true;
		for (Rectangle r : rectangles) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(makeRectangle(r));
		}
		sb.append("}");
		return sb.toString();
	}
	
	protected String makeRectangle(Rectangle r) {
		if (r == null) {
			return "null";
		}
		Formatter formatter = new Formatter();
		formatter.format("new Rectangle(%d, %d, %d, %d)", r.x, r.y, r.width,
				r.height);
		return formatter.toString();
	}
	
	protected String makeStringArray(String[] strings) {
		if (strings == null) {
			return "null";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("new String[] {");
		boolean first = true;
		for (String s : strings) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append("\"");
			sb.append(s);
			sb.append("\"");
		}
		sb.append("}");
		return sb.toString();
	}
	
	protected String makeIntArray(int[][] values) {
		StringBuilder sb = new StringBuilder();
		sb.append("new int[][] {");
		boolean first = true;
		for (int[] v : values) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(makeIntArray(v));
		}
		sb.append("}");
		return sb.toString();
	}

	public String makeIntArray(int[] v) {
		StringBuilder sb = new StringBuilder();
		sb.append("new int[] {");
		boolean first = true;
		for (int i : v) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(i);
		}
		sb.append("}");
		return sb.toString();
	}


	public void setup(IndentedWriter w, ShowBuilder builder) {
		// do nothing
	}
}
